/*
 * CRC.c
 *
 *  Created on: Jan 20, 2014
 *      Author: ppks
 */

#include "Arduino.h"
#include "CRC.h"

/******************************************************************************/
/* Local Variables Declaration                                                */
/******************************************************************************/


/******************************************************************************/
/* Local Functions Declaration                                                */
/******************************************************************************/


/******************************************************************************/
/* Function Code                                                              */
/******************************************************************************/

/*******************************************************************************
* Function Name:
********************************************************************************
* Summary:
*                                      16   12   5
*  This is the CCITT CRC 16 polynomial X  + X  + X  + 1.
*  This works out to be 0x1021, but the way the algorithm works
*  lets us use 0x8408 (the reverse of the bit pattern).  The high
*  bit is always assumed to be set, thus we only use 16 bits to
*  represent the 17 bit value.
*
* Parameters:
*  None
*
* Return:
*  None
*
*******************************************************************************/
uint16_t CRC_CalcCrc16(uint8_t *data_p, uint16_t length)
{
      uint8_t i;
      uint16_t data;
      uint16_t crc = 0xffff;

      if (length == 0)
            return (~crc);

      do
      {
            for (i=0, data=(uint16_t)0xFF & *data_p++;
                 i < 8;
                 i++, data >>= 1)
            {
                  if ((crc & 0x0001) ^ (data & 0x0001))
                        crc = (crc >> 1) ^ CRC_POLYNOM;
                  else  crc >>= 1;
            }
      } while (--length);

      crc = ~crc;
      data = crc;
      crc = (crc << 8) | (data >> 8 & 0xff);

      return (crc);
}

/*******************************************************************************
* Function Name: CRC_CalcCrc8
********************************************************************************
* Summary:
*  Calc CRC8
*
* Parameters:
*  None
*
* Return:
*  None
*
*******************************************************************************/
uint8_t CRC_CalcCrc8(uint8_t *data_p, uint16_t length)
{
    uint8_t crc = 0x00;
    while (length--)
    {
        byte extract = *data_p++;
        for (uint8_t tempI = 8; tempI; tempI--)
        {
            uint8_t sum = (crc ^ extract) & 0x01;
            crc >>= 1;
            if (sum)
            {
                crc ^= 0x8C;
            }
            extract >>= 1;
        }
    }
    return crc;
}

